import React from "react";
import {Toast } from 'antd-mobile-v2';//导入antd-mobile-v2的Toast
import withHook from "../../utils/Withhook"//导入功能组件withHook
import "./index.scss"//导入CSS样式
import { API } from "../../utils/api";
import {getcurrentcity} from "../../utils/index"//引入获取当前城市的功能函数
import {List,AutoSizer} from 'react-virtualized';//导入工具 呈现大列表和表格数据的组件virtualized
import NavHeader from "../../components/Headnavbar";//引入顶部导航组件
import { BASE_URL } from "../../utils/url";//调用请求头

//封装处理字母索引大小写的方法
const formarCityIndex=(letter)=>{
  switch(letter){
    case "#":
      return "当前定位"
    case "hot":
      return"热门城市"
    default:
      return letter.toUpperCase()//转换成大写
  }
}
//索引在列表中的高度高度
const title_Height=36
//城市在列表中的高度高度
const name_Height=50
//有房源的城市
const cityhaveinfo=['北京','上海','广州','深圳']

class HouseList extends React.Component{

  constructor(props){
    super(props)//使得父类的this对象基础给子类
    //状态
    this.state={
      scitylist:[],//首字母 数组
      sshouzimulist:{},//首字母对应城市 数组
      activeindex:0,//高亮索引，默认为0
    }

    this.citylistComponent=React.createRef()//创建对象
  }


  //功能函数 ：用于处理API获取的城市列表数据，输出成2个数组：首字母排序数组，城市以首字母分类数组
  dealcitylist(list){
    const shouzimulist={}//获取城市以首字母分类数组
    list.forEach(element => {
        //如果某首字母类别城市存在,放入
        if(shouzimulist[element.short[0]]){shouzimulist[element.short[0]].push(element)}
        //如果某首字母类别城市不存在，新建，并放入
        else{shouzimulist[element.short[0]]=[element]}
    });

    //获取数组的每一个键值，并返回一个数组,最后sort降序排序
    const citylist = Object.keys(shouzimulist).sort()

    return{shouzimulist,citylist}
    }

  //调用API：获取城市列表
  async getcitylist(){
    //获取城市列表
    const res=await API.get("/area/city?level=1")
    //调用上面的功能函数，将获得的城市列表处理成2个函数
    const {citylist,shouzimulist}=this.dealcitylist(res.data.body)
    //获取热门城市数据
    const res1=await API.get("/area/hot")//获取热门城市数据
    shouzimulist["hot"]=(res1.data.body) //城市列表 添加  hot：城市
    citylist.unshift("hot")   //首字母索引列表 添加 hot：0 
    //获取当前城市
    const curcity= await getcurrentcity()//判断本地是否存储了选择的城市，没有的话默认为当前定位城市
    
    shouzimulist["#"]=[]//城市列表 添加  #：当前城市城市
    shouzimulist["#"].push(curcity)
    
    citylist.unshift("#")//首字母索引列表 添加 #：0 
    
    this.setState(    //更新
      {
        scitylist:citylist,//存入城市信息
        sshouzimulist:shouzimulist,//存入城市-索引信息
      })}

  //点击事件：切换城市（城市）
  changecity=(label,value)=>{
    if(cityhaveinfo.indexOf(label)>-1){
      //判断是否是北京上海广州深圳，,切换，并存储到本地作为当前城市（label为城市名，value为城市值）
      localStorage.setItem("hkzf_city",JSON.stringify({label,value}))
      //路由返回首页
      {this.props.to(-1)}
      //没有，则toast显示无妨无房源
    }else{
      Toast.info("该城市暂无房源数据",1,null,false)
    }
  }

  //点击事件：点击城市 右侧对应索引高亮（startIndex点击索引的位置）
  onRowsRendered=({startIndex})=>{
    if(this.state.activeindex!==startIndex){
      this.setState({
        activeindex:startIndex
      })}}
                                                                                                      
  //功能函数：城市列表每行高度计算(该字母索引下的城市为一行（包含标签索引）)
  getRowHeight=({index})=>{
    //每行高度=索引高度+所含城市数量*城市高度
    //titleheight+sshouzimulist[citylist[index]].length*Name_Height
    const {scitylist,sshouzimulist}=this.state
    const letter=scitylist[index]
    return (title_Height+sshouzimulist[letter].length*name_Height)
  }

//渲染函数：返回值就是渲染页面的内容每一行
  rowRenderer=({
    key, // Unique key within array of rows
    index, // Index of row within collection索引号（）
    style, // Style object to be applied to row (to position it)样式
  }) =>{
    //获取索引对应字母
    const {scitylist,sshouzimulist}=this.state
    //渲染时时按照首字母一样的城市作为一行进行渲染的,所以第N行，表示第N个字母（从0开始）
    const letter=scitylist[index]
    //渲染每一行
    return (
      <div key={key} style={style} className="city"  >
        {/* 渲染索引对应的字母 */}
        <div className="title">{formarCityIndex(letter)}</div>
        {/* 渲染字母下的每一个城市 */}
        {sshouzimulist[letter].map(item=> 
          <div className="name" key={item.value} 
          // 绑定切换城市点击事件
          onClick={()=>this.changecity(item.label,item.value)}>{item.label}</div>)}
      </div>
    );
  }

  //渲染函数，渲染右侧索引
  rendercitylist=()=>{
    return (this.state.scitylist.map((item,index)=>(
      //scitylist的索引与长列表的索引一直,这里绑定事件直接用index进行跳转
      <li className="city-index-item" key={item} onClick={()=>{this.citylistComponent.current.scrollToRow(index)}}>
        {/* 展示是否高亮 */}
      <span className={this.state.activeindex===index?"index-active":""}>{item==="hot"?"热":item.toUpperCase()}</span>
    </li>
    ))
    )
  }
  //生命周期开始
  async componentDidMount(){
    await this.getcitylist();//获取城市列表
    //调用measureAllRows，可以提前计算list中每一行的高度，实现scrollToRow精确跳转（因为scrollToRow只能跳转到渲染过的索引上）
    this.citylistComponent.current.measureAllRows();
  }


    render(){
        return(
        <div className="citylist">
            {/* 顶部导航 */}
            <NavHeader title={"城市选择"}></NavHeader>
            {/* 列表组件 */}
            <AutoSizer>
            {({width,height})=>(
                        <List
                        ref={this.citylistComponent}//ref对象于指定关联组件
                        width={width}//表宽
                        height={height}//表高
                        rowCount={this.state.scitylist.length}//行数
                        rowHeight={this.getRowHeight}//行高（调用行高函数）
                        rowRenderer={this.rowRenderer}//渲染每一行内容 调用渲染函数
                        onRowsRendered={this.onRowsRendered}//点击事件，获取当前点击行的索引值
                        scrollToAlignment="start"/>
                )}
            </AutoSizer>
            {/* //右侧索引列表组件 */}
            <ul className="city-index">
            {this.rendercitylist()}{/* 调用右侧索引渲染函数 */}
            </ul>
        </div>)}}

const HouseListHook= withHook(HouseList)
export default HouseListHook